package com.im.gateway.tcp.dispatcher;

import com.google.protobuf.InvalidProtocolBufferException;
import com.im.common.ImConstant;
import com.im.common.Message;
import com.im.common.Request;
import com.im.common.Response;
import com.im.gateway.tcp.SessionManager;
import com.im.protocol.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;

/**
 * @Created leijun
 * @Date 2021/9/12 9:31 下午
 */
public class DispatcherInstanceHandler extends ChannelInboundHandlerAdapter {

    /**
     * 与分发层断开连接会调用此方法
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel socketChannel = (SocketChannel) ctx.channel();
        String dispatcherChannelId = socketChannel.remoteAddress().getHostName() + ":" + socketChannel.remoteAddress().getPort();
        DispatcherInstanceManager dispatcherInstanceManager = DispatcherInstanceManager.getInstance();
        dispatcherInstanceManager.remove(dispatcherChannelId);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Message message = new Message((ByteBuf) msg);
        if (ImConstant.MESSSAGE_TYPE_RESPONSE == message.getMessageType()) {
            Response response = message.toResponse();
            if (ImConstant.REQUEST_TYPE_AUTHENTICATE == response.getRequestType()) {
                handleAuthenticateResponse(response);
            } else if (ImConstant.REQUEST_TYPE_SEND_MESSAGE == response.getRequestType()) {
                handleSendMessageResponse(response);
            } else if (ImConstant.REQUEST_TYPE_GROUP_MESSAGE == response.getRequestType()) {
                handleSendGroupMessageResponse(response);
            }
        } else if (ImConstant.MESSAGE_TYPE_REQUEST == message.getMessageType()) {
            Request request = message.toRequest();
            if (ImConstant.REQUEST_TYPE_PUSH_MESSAGE == request.getRequestType()) {
                handlePushMessageRequest(request);
            } else if (ImConstant.REQUEST_TYPE_PUSH_GROUP_MESSAGE == request.getRequestType()) {
                handlePushGroupMessageRequest(request);
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    /**
     * 处理分发层的用户认证响应请求
     * @param response
     * @throws InvalidProtocolBufferException
     */
    public void handleAuthenticateResponse(Response response) throws InvalidProtocolBufferException {
        AuthenticateResponseProto.AuthenticateResponse authenticateResponse =
                AuthenticateResponseProto.AuthenticateResponse.parseFrom(response.getBody());
        Long uid = authenticateResponse.getUid();
        SessionManager sessionManager = SessionManager.getInstance();
        sessionManager.writeAndFlush(uid, response.getBuf());
    }

    /**
     * 处理分发层的单聊消息响应请求
     * @param response
     * @throws InvalidProtocolBufferException
     */
    public void handleSendMessageResponse(Response response) throws InvalidProtocolBufferException {
        MessageResponseProto.MessageResponse messageResponse =
                MessageResponseProto.MessageResponse.parseFrom(response.getBody());
        Long senderId = messageResponse.getSenderId();
        SessionManager sessionManager = SessionManager.getInstance();
        SocketChannel socketChannel = sessionManager.getSession(senderId);
        socketChannel.writeAndFlush(response.getBuf());
    }

    /**
     * 处理分发层的群聊消息响应请求
     * @param response
     * @throws InvalidProtocolBufferException
     */
    private void handleSendGroupMessageResponse(Response response) throws InvalidProtocolBufferException {
        GroupMessageResponseProto.GroupMessageResponse messageResponse =
                GroupMessageResponseProto.GroupMessageResponse.parseFrom(response.getBody());
        Long senderId = messageResponse.getSenderId();
        SessionManager sessionManager = SessionManager.getInstance();
        SocketChannel socketChannel = sessionManager.getSession(senderId);
        socketChannel.writeAndFlush(response.getBuf());
    }

    /**
     * 处理分发层的消息推送请求
     * @param request
     * @throws InvalidProtocolBufferException
     */
    private void handlePushMessageRequest(Request request) throws InvalidProtocolBufferException {
        PushMessageRequestProto.PushMessageRequest pushMessageRequest =
                PushMessageRequestProto.PushMessageRequest.parseFrom(request.getBody());
        Long receiverId = pushMessageRequest.getReceiverId();
        SessionManager sessionManager = SessionManager.getInstance();
        SocketChannel socketChannel = sessionManager.getSession(receiverId);
        socketChannel.writeAndFlush(request.getBuf());
    }

    /**
     * 处理分发层的群消息推送请求
     * @param request
     * @throws InvalidProtocolBufferException
     */
    private void handlePushGroupMessageRequest(Request request) throws InvalidProtocolBufferException {
        PushGroupMessageRequestProto.PushGroupMessageRequest pushGroupMessageRequest =
                PushGroupMessageRequestProto.PushGroupMessageRequest.parseFrom(request.getBody());
        Long receiverId = pushGroupMessageRequest.getReceiverId();
        SessionManager sessionManager = SessionManager.getInstance();
        SocketChannel socketChannel = sessionManager.getSession(receiverId);
        socketChannel.writeAndFlush(request.getBuf());
    }
}
